//@author A0105740R
package rightnow.parser.cmdline;

import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class is used by CmdTaskParserCore to generate list of tokens.
 */
class Tokenizer {
	
	/**
	 * Marks up all texts in a given pattern from a tokenList
	 * @param tokenList
	 * @param regex
	 * @param targetType
	 */
	public static void tokenizeAll(List<Token> tokenList, 
			String regex,TokenType targetType) {
		
		ListIterator<Token> iter = tokenList.listIterator();
		Pattern pattern = Pattern.compile(regex);
		while (iter.hasNext()) {
			Token currentToken = iter.next();
			if (currentToken.getTokenType() == TokenType.UNDET) {
				String originStr = currentToken.getTokenString();
				Matcher matcher = pattern.matcher(originStr);
				if (matcher.find()) {
					int startInd = matcher.start();
					int endInd = matcher.end();
					String sub1 = originStr.substring(0, startInd).trim();
					String sub2 = originStr.substring(startInd, endInd);
					String sub3 = originStr.substring(endInd).trim();
					iter.remove();
					if (!sub1.isEmpty()) {
						iter.add(new Token(sub1));
					}
					iter.add(new Token(sub2, targetType));
					if (!sub3.isEmpty()) {
						iter.add(new Token(sub3));
						iter.previous();
					}
				}
			}
		}
	}
	
	/**
	 * Marks up all texts in a given pattern that are directly after an array
	 * of identifiers.
	 * @param tokenList tokenString after idtfType is trimmed
	 * @param idtfType
	 * @param regex
	 * @param targetType
	 * @param limit	<= 0 if unlimited
	 */
	public static void tokenizeAllDirectAfter(List<Token> tokenList, 
			TokenType[] idtfTypeArr,
			String regex, TokenType targetType, int limit) {
		
		ListIterator<Token> iter = tokenList.listIterator();
		Pattern pattern = Pattern.compile(regex);
		
		while (iter.hasNext()) {
			Token idtfToken = iter.next();
			if (Arrays.asList(idtfTypeArr).contains(idtfToken.getTokenType()) 
					&& iter.hasNext()) {
				for (int i = 0 ; limit <= 0 || i < limit ; i++) {
					Token currentToken = iter.next();
					if (currentToken.getTokenType() == TokenType.UNDET) {
						String originStr = currentToken.getTokenString();
						Matcher matcher = pattern.matcher(originStr);
						if (matcher.lookingAt()) {
							int startInd = matcher.start();
							int endInd = matcher.end();
							String sub2 = originStr.substring(startInd, endInd);
							String sub3 = originStr.substring(endInd).trim();
							iter.remove();
							iter.add(new Token(sub2, targetType));
							if (!sub3.isEmpty()) {
								iter.add(new Token(sub3));
								iter.previous();
							}
						}
						else {
							break;
						}
					}
					else if (currentToken.getTokenType() 
							== idtfToken.getTokenType()) {
						iter.previous();
						break;
					}
					else {
						break;
					}
				}
			}
		}
	}
	
	/**
	 * Marks up all texts in a given pattern that are directly after
	 * an identifier.
	 * @param tokenList
	 * @param idtfType
	 * @param regex
	 * @param targetType
	 * @param limit
	 */
	public static void tokenizeAllDirectAfter(List<Token> tokenList, 
			TokenType idtfType,
			String regex, TokenType targetType, int limit) {
		
		tokenizeAllDirectAfter(tokenList, 
				new TokenType[] {idtfType}, regex, targetType, limit);
	}
}
